﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DynaPrecision.Numerical
{
	using FunctionAnalysis;
	public class NewtonianSolver<TInput, TResult> : IFunctionSolver<TInput, TResult>
	{

		public TInput InitialGuess { get; set; }
		public TInput Resolution { get; set; }

		public NewtonianSolver()
		{
			InitialGuess = DefaultValueProvider<TInput>.GetZero();
			Resolution = DefaultValueProvider<TInput>.GetDefaultResolution();
		}

		public TInput SolveFor(Func<TInput, TResult> functor, Func<TInput, TResult> derivative, TInput initialGuess, TResult RighthandSide)
		{
			dynamic Current = functor(initialGuess), error = Current - RighthandSide, x = initialGuess;
			while ((error > 0 ? error : -error) > Resolution)
			{
				x -= error / derivative(x);
				Current = functor(x);
				error = Current - RighthandSide;
			}
			return x;
		}
		#region IFunctionSolver<TInput,TResult> Members

		public TInput SolveFor<TFunction>(TFunction functor, TResult RighthandSide)
			where TFunction : IFunction<TInput, TResult>
		{

			return SolveFor(functor.Functor,functor.Derivative.Functor, InitialGuess, RighthandSide);
		}

		#endregion
	}
}
